package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
@RequiredArgsConstructor
public class ReportServiceImpl implements ReportService {

    private final OrderMapper orderMapper;

    private final UserMapper userMapper;

    private final WorkspaceService workspaceService;



    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {

        List<LocalDate> localDates = getLocalDates(begin, end);

        String dataList = StringUtils.join(localDates, ",");
        List<Double> list=new ArrayList<>();
        for (LocalDate date : localDates) {
            //已完成订单的状态合计
            //select sum(amount) from orders where status=5 and order_time>? and order_time<?
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map=new HashMap();
            map.put("begin",beginTime);
            map.put("end",endTime);
            map.put("status",Orders.COMPLETED);
            list.add(orderMapper.sumByMap(map));
        }
        String turnoverList=StringUtils.join(list, ",");
        System.out.println(turnoverList);
        return new TurnoverReportVO(dataList,turnoverList);
    }
    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> localDates = getLocalDates(begin, end);

        String dataList = StringUtils.join(localDates, ",");
        List<Integer> newList =new ArrayList<>();
        List<Integer> allList =new ArrayList<>();
        for (LocalDate date : localDates) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map=new HashMap();
            map.put("end",endTime);
            allList.add(userMapper.getByMap(map));
            map.put("begin",beginTime);
            //select count(*) from user where create_time < ? and create_time > ?
            newList.add(userMapper.getByMap(map));

        }
        String newUserList = StringUtils.join(newList, ",");

        String totalUserList=StringUtils.join(allList, ",");
        return new UserReportVO(dataList,totalUserList,newUserList);
    }

    private static List<LocalDate> getLocalDates(LocalDate begin, LocalDate end) {
        List<LocalDate> localDates = new ArrayList<>();

        while (!begin.isAfter(end)) {
            localDates.add(begin);
            begin = begin.plusDays(1);
        }
        return localDates;
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {

        List<LocalDate> localDates = getLocalDates(begin, end);
        String dataList = StringUtils.join(localDates, ",");

        List<Integer> allList =new ArrayList<>();
        List<Integer> validList =new ArrayList<>();
        //订单总数
        int totalOrderCount = 0;

        //有效订单数
        int validOrderCount=0;

        for (LocalDate date : localDates) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map=new HashMap();
            map.put("begin",beginTime);
            map.put("end",endTime);
            Integer all=orderMapper.countByMap(map);
            totalOrderCount+=all;
            allList.add(all);
            map.put("status",Orders.COMPLETED);
            Integer valid=orderMapper.countByMap(map);
            validOrderCount+=valid;
            validList.add(valid);
        }

        //每日订单数，以逗号分隔，例如：260,210,215
        String orderCountList=StringUtils.join(allList, ",");

        //每日有效订单数，以逗号分隔，例如：20,21,10
        String validOrderCountList=StringUtils.join(validList, ",");

        //订单完成率
        double orderCompletionRate=0.0;
        if(totalOrderCount!=0){
            orderCompletionRate=  validOrderCount * 1.0 / totalOrderCount;
        }

        return new OrderReportVO(dataList,orderCountList,validOrderCountList,totalOrderCount,validOrderCount,orderCompletionRate);
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
/*
         select od.name ,sum(od.number) number orders_detail od , orders o
         where o.id = od.order_id and o.status=5 and order_time > begin and order_time > end
         group by od.name
         order by number desc
         limit 0 10
         */
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);

        Map map=new HashMap();
        map.put("begin",beginTime);
        map.put("end",endTime);
        map.put("status",Orders.COMPLETED);
        List<GoodsSalesDTO> goodsSalesDTOS = orderMapper.getByMapTop10(map);
        List<String> names = goodsSalesDTOS.stream().map(GoodsSalesDTO::getName).collect(Collectors.toList());
        String nameList = StringUtils.join(names, ",");
        List<Integer> numbers = goodsSalesDTOS.stream().map(GoodsSalesDTO::getNumber).collect(Collectors.toList());
        String numberList = StringUtils.join(numbers, ",");

        return new SalesTop10ReportVO(nameList,numberList);
    }
    /**
     * 导出运营数据报表
     * @param response
     */
    @Override
    public void export(HttpServletResponse response) {
        //查询数据库，获取营业数据--查询最近三十天

        LocalDate beginTime = LocalDate.now().minusDays(30);
        LocalDate endTime = LocalDate.now().minusDays(1);

        LocalDateTime end =
                LocalDateTime.of(endTime, LocalTime.MAX);
        LocalDateTime begin = LocalDateTime.of(beginTime, LocalTime.MIN);

        BusinessDataVO data ;
        data = workspaceService.getBusinessData(begin, end);
        System.out.println(data);
        //通过poi将数据写入文件中
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("template/sky-take-out.xlsx");

        try {
//            //基于模板文件创建新的文件
            XSSFWorkbook excel = new XSSFWorkbook(in);
//            //获取标签页
            XSSFSheet sheet = excel.getSheet("Sheet1");
            sheet.getRow(2).getCell(1).setCellValue("时间："+beginTime+"至"+endTime);
            //填充营业额
            XSSFRow row = sheet.getRow(4);
            row.getCell(2).setCellValue(data.getTurnover());
            //填充订单完成率
            row.getCell(4).setCellValue(data.getOrderCompletionRate());
            //填充新增用户数
            row.getCell(6).setCellValue(data.getNewUsers());
            //填充有效订单
            row=sheet.getRow(5);
            row.getCell(2).setCellValue(data.getValidOrderCount());
            row.getCell(4).setCellValue(data.getUnitPrice());
            int r =8;
            while(!beginTime.isAfter(endTime)){
                row = sheet.getRow(r);
                row.getCell(1).setCellValue(beginTime.toString());
                data = workspaceService.getBusinessData(LocalDateTime.of(beginTime, LocalTime.MIN),LocalDateTime.of(beginTime, LocalTime.MAX) );
                //填充营业额
                row.getCell(2).setCellValue(data.getTurnover());
                //填充订单完成率
                row.getCell(4).setCellValue(data.getOrderCompletionRate());
                //填充新增用户数
                row.getCell(6).setCellValue(data.getNewUsers());
                //填充有效订单
                row.getCell(3).setCellValue(data.getValidOrderCount());
                //填充平均客单价
                row.getCell(5).setCellValue(data.getUnitPrice());
                beginTime = beginTime.plusDays(1);
                r++;
            }
            //通过输出流将文件下载到客户端浏览器
            ServletOutputStream out = response.getOutputStream();
            excel.write(out);

            out.close();
            excel.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
